package com.poizon.infrastructure.idem;

import com.poizon.infrastructure.idem.core.annoations.config.AopConfig;
import com.poizon.infrastructure.idem.core.domain.IdemDomainInit;
import com.poizon.infrastructure.idem.core.domain.value.config.IdemConstants;
import com.poizon.infrastructure.idem.core.hook.IdemThreadPoolHook;
import com.poizon.infrastructure.idem.core.util.IIdemUtil;
import com.poizon.infrastructure.idem.core.util.impl.IdemUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Import(value = {
        BannerPrint.class, IdemDomainInit.class, AopConfig.class
})
@Slf4j
public class IdemAutoConfig {
    /**
     * 动态线程池
     * todo: 优化线程池参数
     */
    @Bean(name = "idemThreadPool")
    public ThreadPoolExecutor idemThreadPool() {
        log.info("[通用幂等框架] 初始化幂等响应刷新线程池");
        ThreadPoolExecutor idemAsyncSubmitRespExecutor = new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors() * 2 * 4,
                Runtime.getRuntime().availableProcessors() * 2 * 4,
                1000L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(2000));

        // 添加优雅关闭钩子
        IdemThreadPoolHook.gracefulShutdown(idemAsyncSubmitRespExecutor);
        return idemAsyncSubmitRespExecutor;
    }

    @Bean
    public IIdemUtil idemUtil(@Qualifier(value = "idemThreadPool") ThreadPoolExecutor threadPoolExecutor, Environment env) {
        log.info("[通用幂等框架] 初始化幂等配置");

        IdemConstants.IDEM_KEY_PREFIX = env.getProperty(IdemConstants.POIZON_IDEM_PREFIX, IdemConstants.IDEM_KEY_PREFIX);
        IdemConstants.DEFAULT_IDEM_KEY_EXPIRE_TIME = env.getProperty(IdemConstants.POIZON_IDEM_EXPIRE_TIME, Long.class, IdemConstants.DEFAULT_IDEM_KEY_EXPIRE_TIME);
        IdemConstants.DEFAULT_IDEM_KEY_TIME_UNIT = env.getProperty(IdemConstants.POIZON_IDEM_TIME_UNIT, TimeUnit.class, IdemConstants.DEFAULT_IDEM_KEY_TIME_UNIT);
        IdemConstants.DEFAULT_MAX_RETRY_TIMES = env.getProperty(IdemConstants.POIZON_IDEM_MAX_RETRY_TIMES, Integer.class, IdemConstants.DEFAULT_MAX_RETRY_TIMES);
        IdemConstants.IDEM_RETRY_WAIT_TIME = env.getProperty(IdemConstants.POIZON_IDEM_RETRY_TIME, Integer.class, IdemConstants.IDEM_RETRY_WAIT_TIME);
        IdemConstants.DB_ERROR_THRESHOLD = env.getProperty(IdemConstants.POIZON_IDEM_DB_ERROR_THREASHOLD, Integer.class, IdemConstants.DB_ERROR_THRESHOLD);
        IdemConstants.IDEM_DB_STORE_TYPE = env.getProperty(IdemConstants.DB_STORE_TYPE_CONFIG, String.class, IdemConstants.IDEM_DB_STORE_TYPE);
        IdemConstants.DEFAULT_REPEATED_SUBMIT_KEY_TIME_UNIT = env.getProperty(IdemConstants.POIZON_REPEATED_SUBMIT_TIME_UNIT, TimeUnit.class, IdemConstants.DEFAULT_REPEATED_SUBMIT_KEY_TIME_UNIT);
        IdemConstants.DEFAULT_REPEATED_SUBMIT_KEY_EXPIRE_TIME = env.getProperty(IdemConstants.POIZON_IDEM_REPEATED_SUBMIT_EXPIRE_TIME, Long.class, IdemConstants.DEFAULT_REPEATED_SUBMIT_KEY_EXPIRE_TIME);
        IdemConstants.REPEATED_SUBMIT_KEY_PREFIX = env.getProperty(IdemConstants.POIZON_REPEATED_PREFIX, String.class, IdemConstants.REPEATED_SUBMIT_KEY_PREFIX);

        return new IdemUtil(threadPoolExecutor);
    }


}
